package com.chenfan.mcn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenfan.common.vo.Response;
import com.chenfan.common.vo.ResponseCode;
import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.constant.BillCodeCst;
import com.chenfan.mcn.dao.DocKocpmHeaderMapper;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.component.CodeGenerateHelper;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.dto.KocProjectSearchDto;
import com.chenfan.mcn.model.dto.KocRedInfoDto;
import com.chenfan.mcn.model.dto.KocpmHeaderDto;
import com.chenfan.mcn.model.vo.KocProjectSearchVO;
import com.chenfan.mcn.model.vo.KocpmHeaderVo;
import com.chenfan.mcn.service.DocKocpmHeaderService;
import com.chenfan.mcn.service.DocKocpmRedstarService;
import com.chenfan.mcn.service.StarBasicDataService;
import com.chenfan.mcn.service.StarPlatformInfoService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2022-05-21 14:22
 */
@Service
public class DocKocpmHeaderServiceImpl extends ServiceImpl<DocKocpmHeaderMapper, DocKocpmHeader> implements DocKocpmHeaderService {

    @Autowired
    private DocKocpmRedstarService docKocpmRedstarService;

    @Autowired
    private StarPlatformInfoService starPlatformInfoService;

    @Autowired
    private StarBasicDataService starBasicDataService;

    @Resource
    private DocKocpmHeaderMapper docKocpmHeaderMapper;

    @Override
    public Response<Page<KocpmHeaderDto>> getPage(KocpmHeaderVo vo, int pageNo, int pageSize) {
        Page<DocKocpmHeader> page = baseMapper.selectPage(new Page<>(pageNo, pageSize),
                new QueryWrapper<DocKocpmHeader>().lambda()
                        .like(StringUtils.isNotEmpty(vo.getKocpmName()), DocKocpmHeader::getKocpmName, vo.getKocpmName())
                        .like(StringUtils.isNotEmpty(vo.getCreateName()), DocKocpmHeader::getCreateName, vo.getCreateName())
                        .ge(Objects.nonNull(vo.getCreateStartDate()), DocKocpmHeader::getCreateDate, vo.getCreateStartDate())
                        .le(Objects.nonNull(vo.getCreateEndDate()), DocKocpmHeader::getCreateDate, vo.getCreateEndDate())
                        .eq(DocKocpmHeader::getTenantId, UserVoContextHolder.getUserVo().getTenantId())
                        .in(!CollectionUtils.isEmpty(vo.getUserIds()), DocKocpmHeader::getOwnerId, vo.getUserIds())
                        .in(!CollectionUtils.isEmpty(vo.getCompanyIds()), DocKocpmHeader::getCompanyId, vo.getCompanyIds())
                        .orderByDesc(DocKocpmHeader::getCreateDate));
        Map<String,Object> result = new HashMap<>(4);
        result.put("list", ListUtils.defaultIfNull(page.getRecords(), Collections.EMPTY_LIST));
        result.put("total",page.getTotal());
        return new Response(ResponseCode.SUCCESS, result);
    }

    @Override
    public Response<List<KocpmHeaderDto>> getList(KocpmHeaderVo vo) {
        List<DocKocpmHeader> list = baseMapper.selectList(new QueryWrapper<DocKocpmHeader>().lambda()
                .like(StringUtils.isNotEmpty(vo.getKocpmName()), DocKocpmHeader::getKocpmName, vo.getKocpmName())
                .like(StringUtils.isNotEmpty(vo.getCreateName()), DocKocpmHeader::getCreateName, vo.getCreateName())
                .ge(Objects.nonNull(vo.getCreateStartDate()), DocKocpmHeader::getCreateDate, vo.getCreateStartDate())
                .le(Objects.nonNull(vo.getCreateEndDate()), DocKocpmHeader::getCreateDate, vo.getCreateEndDate())
                .in(!CollectionUtils.isEmpty(vo.getUserIds()), DocKocpmHeader::getOwnerId, vo.getUserIds())
                .in(!CollectionUtils.isEmpty(vo.getCompanyIds()), DocKocpmHeader::getCompanyId, vo.getCompanyIds())
                .eq(DocKocpmHeader::getTenantId, UserVoContextHolder.getUserVo().getTenantId())
                .eq(DocKocpmHeader::getStatus, vo.getStatus())
                .orderByDesc(DocKocpmHeader::getKocpmId));
        if (CollectionUtils.isEmpty(list)) {
            return new Response(ResponseCode.SUCCESS, Collections.EMPTY_LIST);
        }
        List<KocpmHeaderDto> result = list.stream().map(record -> {
            KocpmHeaderDto dto = new KocpmHeaderDto();
            BeanUtils.copyProperties(record, dto, KocpmHeaderDto.class);
            return dto;
        }).collect(Collectors.toList());
        return new Response(ResponseCode.SUCCESS, result);
    }

    @Override
    public Response addOrUpdate(KocpmHeaderVo vo) {
        //名称存在校验
        List<DocKocpmHeader> list = baseMapper.selectList(new QueryWrapper<DocKocpmHeader>().lambda()
                .eq(StringUtils.isNotEmpty(vo.getKocpmName()), DocKocpmHeader::getKocpmName, vo.getKocpmName())
                .ne(Objects.nonNull(vo.getKocpmId()), DocKocpmHeader::getKocpmId, vo.getKocpmId())
                .eq(DocKocpmHeader::getTenantId, UserVoContextHolder.getUserVo().getTenantId()));
        if (!CollectionUtils.isEmpty(list)) {
            return Response.error(McnErrorCode.KOCPMNAME_EXISTS);
        }

        DocKocpmHeader record = new DocKocpmHeader();
        BeanUtils.copyProperties(vo, record, DocKocpmHeader.class);
        record.setOwnerId(UserVoContextHolder.getUserId());
        record.setOwnerName(UserVoContextHolder.getUserName());
        record.setUpdateBy(UserVoContextHolder.getUserId());
        record.setUpdateName(UserVoContextHolder.getUserName());
        record.setUpdateDate(LocalDateTime.now());
        if (Objects.isNull(vo.getKocpmId())) {
            record.setCreateBy(UserVoContextHolder.getUserId());
            record.setCreateName(UserVoContextHolder.getUserName());
            record.setCreateDate(LocalDateTime.now());
            record.setCompanyId(UserVoContextHolder.getCompanyId());
            record.setTenantId(UserVoContextHolder.getTenantId());
            record.setKocpmCode(CodeGenerateHelper.getCode(BillCodeCst.KOC_PM));
            this.baseMapper.insert(record);
        } else {
            BeanUtils.copyProperties(vo, record, DocKocpmHeader.class);
            this.baseMapper.updateById(record);
            docKocpmRedstarService.remove(new QueryWrapper<DocKocpmRedstar>().lambda().eq(DocKocpmRedstar::getKocpmId, vo.getKocpmId()));
        }
        vo.getDetails().stream().forEach(detail -> {
            detail.setKocpmId(record.getKocpmId());
            detail.setCreateBy(UserVoContextHolder.getUserId());
            detail.setCreateName(UserVoContextHolder.getUserName());
            detail.setCreateDate(LocalDateTime.now());
            detail.setCompanyId(UserVoContextHolder.getCompanyId());
            detail.setTenantId(UserVoContextHolder.getTenantId());
        });
        docKocpmRedstarService.saveBatch(vo.getDetails());
        return new Response(ResponseCode.SUCCESS);
    }

    @Override
    public Response<KocpmHeaderDto> getInfo(KocProjectSearchDto vo) {
        if (Objects.isNull(vo.getKocpmId())) {
            return new Response(ResponseCode.SUCCESS);
        }
        DocKocpmHeader entity = baseMapper.selectById(vo.getKocpmId());
        if (Objects.isNull(entity)) {
            return new Response(ResponseCode.SUCCESS);
        }
        KocpmHeaderDto result = new KocpmHeaderDto();
        BeanUtils.copyProperties(entity, result, KocpmHeaderDto.class);

        //查询子表信息
        List<DocKocpmRedstar> redstars = docKocpmRedstarService.list(new QueryWrapper<DocKocpmRedstar>().lambda().eq(DocKocpmRedstar::getKocpmId, vo.getKocpmId())
                .notIn(!CollectionUtils.isEmpty(vo.getExistStarPlatInfoIds()), DocKocpmRedstar::getStarPlatformInfoId, vo.getExistStarPlatInfoIds())
                .last(!CollectionUtils.isEmpty(vo.getExistStarPlatInfoIds()), "limit " + vo.getPageSize()));
        if (CollectionUtils.isEmpty(redstars)) {
            return Response.success(result);
        }
        //查询红人平台信息
        Set<Long> starPlatformInfoIds = redstars.stream().map(x -> x.getStarPlatformInfoId()).collect(Collectors.toSet());
        List<StarPlatformInfo> starPlatformInfos = starPlatformInfoService.selectList(new QueryWrapper<StarPlatformInfo>().lambda().in(StarPlatformInfo::getId, starPlatformInfoIds)
                .like(StringUtils.isNotEmpty(vo.getPlatNickName()), StarPlatformInfo::getPlatNickName, vo.getPlatNickName()));
        if(CollectionUtils.isEmpty(starPlatformInfos)){
            return Response.success(result);
        }
        Map<Long, StarPlatformInfo> starPlatformInfoMap = starPlatformInfos.stream().collect(Collectors.toMap(StarPlatformInfo::getId, x -> x, (x, y) -> x));
        //查询红人信息
        Set<Long> starIds = starPlatformInfos.stream().map(x -> x.getStarId()).collect(Collectors.toSet());
        List<StarBasicData> starBasicDatas = starBasicDataService.selectList(new QueryWrapper<StarBasicData>().lambda().in(StarBasicData::getId, starIds)
                .like(StringUtils.isNotEmpty(vo.getStarName()), StarBasicData::getStarName, vo.getStarName())
                .like(StringUtils.isNotEmpty(vo.getStarNickname()), StarBasicData::getStarNickname, vo.getStarNickname()));
        if(CollectionUtils.isEmpty(starBasicDatas)){
            return Response.success(result);
        }
        Map<Long, StarBasicData> starBasicDataMap = starBasicDatas.stream().collect(Collectors.toMap(StarBasicData::getId, x -> x, (x, y) -> x));

        List<KocRedInfoDto> dtos = redstars.stream().map(info -> {
            KocRedInfoDto dto = new KocRedInfoDto();
            BeanUtils.copyProperties(info, dto, KocRedInfoDto.class);
            StarPlatformInfo starPlatformInfo = starPlatformInfoMap.get(info.getStarPlatformInfoId());
            if (Objects.isNull(starPlatformInfo)) {
                return null;
            }
            if (Objects.nonNull(starPlatformInfo)) {
                dto.setKocpmId(entity.getKocpmId());
                dto.setStarPlatformInfoId(starPlatformInfo.getId());
                dto.setPlatformName(starPlatformInfo.getPlatformName());
                dto.setPlatNickName(starPlatformInfo.getPlatNickName());
                StarBasicData starBasicData = starBasicDataMap.get(starPlatformInfo.getStarId());
                if (Objects.isNull(starBasicData)) {
                    return null;
                }
                BeanUtils.copyProperties(starBasicData, dto, KocRedInfoDto.class);
                dto.setCreateDate(starPlatformInfo.getCreateDate());
                dto.setStarId(starBasicData.getId());
            }
            return dto;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        result.setDetails(dtos);
        return Response.success(result);
    }


    @Override
    public Response enable(KocpmHeaderVo vo) {
        DocKocpmHeader entity = new DocKocpmHeader();
        BeanUtils.copyProperties(vo, entity, DocKocpmHeader.class);
        entity.setUpdateBy(UserVoContextHolder.getUserId());
        entity.setUpdateName(UserVoContextHolder.getUserName());
        entity.setUpdateDate(LocalDateTime.now());
        int i = baseMapper.updateById(entity);
        if (i > 0) {
            return new Response(ResponseCode.SUCCESS);
        }
        return new Response(ResponseCode.FAIL);
    }

    @Override
    public List<KocProjectSearchVO> kocProjectSearch(KocProjectSearchDto kocProjectSearchDto) {
        List<KocProjectSearchVO> list = docKocpmHeaderMapper.selectByStarBasicDataPm(kocProjectSearchDto);
        return list;
    }

    @Override
    public Page<KocProjectSearchVO> kocMonthlySearch(KocProjectSearchDto kocProjectSearchDto) {
        Page<KocProjectSearchVO> page = docKocpmHeaderMapper.selectByStarBasicDataMonthly(new Page(kocProjectSearchDto.getPageNum(), kocProjectSearchDto.getPageSize()), kocProjectSearchDto);
        return page;
    }
}
